package com.sanri.tools.modules.mock.l7.websocket.chat.service.ws;

import com.alibaba.fastjson.JSON;
import com.sanri.tools.modules.core.dtos.ResponseDto;
import com.sanri.tools.modules.core.utils.SnowflakeIdWorker;
import com.sanri.tools.modules.mock.l7.websocket.chat.domain.Message;
import com.sanri.tools.modules.mock.l7.websocket.chat.repository.ChatGroupRepository;
import com.sanri.tools.modules.mock.l7.websocket.chat.repository.ChatUserRepository;
import com.sanri.tools.modules.mock.l7.websocket.chat.repository.MessageRepository;
import com.sanri.tools.modules.mock.l7.websocket.chat.service.ws.message.ChatSocketMessageHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.java_websocket.exceptions.WebsocketNotConnectedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class ChatSupport {

    @Autowired
    private MessageRepository messageRepository;
    @Autowired
    private ChatUserRepository chatUserRepository;

    @Autowired
    private ChatGroupRepository chatGroupRepository;

    public static final Map<String,ChatSession> sessionMap = new ConcurrentHashMap<>();

    /**
     * session 保活检测 30s 检测一次
     */
    @Scheduled(fixedDelay = 30000)
    public void ping(){
        Iterator<Map.Entry<String, ChatSession>> iterator = sessionMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, ChatSession> next = iterator.next();
            try {
                next.getValue().getWebSocket().sendPing();
            }catch (WebsocketNotConnectedException e){
                log.info("{} 断开连接 ", next.getKey());

                iterator.remove();
            }
        }
    }

    /**
     * 广播消息到群
     * @param groupId
     * @param message
     * @return
     * @throws IOException
     */
    public void boardcastGroup(String groupId, Message chatMessage) throws IOException {
        // 广播到每个有这个群的用户
        List<String> users = chatGroupRepository.groupUsers(groupId);
        for (String user : users) {
            ChatSession chatSession = ChatSupport.sessionMap.get(user);
            if (chatSession != null){
                // 只发送在线用户
                chatMessage.setStatus("succeed");
                ChatSocketMessageHandler.ChatRequestMessage chatRequestMessage = new ChatSocketMessageHandler.ChatRequestMessage(chatMessage);
                chatSession.getWebSocket().send(JSON.toJSONString(chatRequestMessage));
            }
        }

    }

    /**
     * 广播消息到好友
     * @param username
     * @param chatMessage
     */
    public void boardcastToContacts(String username, Message message) throws IOException {
        String [] contacts = chatUserRepository.listContacts(username);
        if (ArrayUtils.isNotEmpty(contacts)) {
            for (String contact : contacts) {
                ChatSession chatSession = ChatSupport.sessionMap.get(contact);
                if (chatSession != null) {
                    Message chatMessage = new Message();
                    chatMessage.setId(SnowflakeIdWorker.getSnowflakeId());
                    chatMessage.setFromContactId(message.getFromContactId());
                    chatMessage.setToContactId(username);
                    chatMessage.setSendTime(message.getSendTime());
                    chatMessage.setType(message.getType());
                    chatMessage.setContent(message.getContent());
                    chatMessage.setStatus("succeed");

                    ChatSocketMessageHandler.ChatRequestMessage chatRequestMessage = new ChatSocketMessageHandler.ChatRequestMessage(chatMessage);
                    chatSession.getWebSocket().send(JSON.toJSONString(chatRequestMessage));
                }
            }
        }
    }

    public void sendMessage(Message chatMessage) throws IOException {
        ChatSession loginUser = sessionMap.get(chatMessage.getFromContactId());
        if (!"system".equals(chatMessage.getFromContactId())) {
            if (loginUser == null) {
                log.info("登录用户, 未登录....");
                return;
            }
        }

        // 检查对方是否为联系人
        String[] listContacts = chatUserRepository.listContacts(chatMessage.getFromContactId());
        if (!ArrayUtils.contains(listContacts, chatMessage.getToContactId())){
            // 检测是否为群消息
            List<String> groups = chatUserRepository.groups(chatMessage.getFromContactId());
            if (!groups.contains(chatMessage.getToContactId())) {
                loginUser.getWebSocket().send(JSON.toJSONString(ResponseDto.err("999").message("对方不是你的好友, 请先添加联系人")));
                return ;
            }
            // 广播群消息
            chatMessage.setStatus("succeed");
            chatMessage.setGroup(true);

            boardcastGroup(chatMessage.getToContactId(), chatMessage);
            messageRepository.storageMessage(chatMessage);
            return ;
        }

        ChatSession chatSession = ChatSupport.sessionMap.get(chatMessage.getToContactId());
        if (chatSession == null) {
            if ("system".equals(chatMessage.getFromContactId())){
                return ;
            }
            if (loginUser.getWebSocket() == null){
                log.error("websocket 断连, 需要重连");
                return;
            }

            Message message = new Message("text", "对方离线", chatMessage.getToContactId(), "system");
            ChatSocketMessageHandler.ChatRequestMessage chatRequestMessage = new ChatSocketMessageHandler.ChatRequestMessage(message);
            loginUser.getWebSocket().send(JSON.toJSONString(chatRequestMessage));

        }else {
            ChatSocketMessageHandler.ChatRequestMessage chatRequestMessage = new ChatSocketMessageHandler.ChatRequestMessage(chatMessage);
            chatMessage.setStatus("succeed");
            chatSession.getWebSocket().send(JSON.toJSONString(chatRequestMessage));
        }

        // 消息存储(暂时消息永远都是成功消息)
        chatMessage.setStatus("succeed");
        messageRepository.storageMessage(chatMessage);
    }
}
